package com.han.hotelplat.service.emtask.impl;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.rubyeye.xmemcached.GetsResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.han.hotelplat.comm.Constant;
import com.han.hotelplat.comm.base.EntityManage;
import com.han.hotelplat.comm.utils.AppHotelPushUtil;
import com.han.hotelplat.comm.utils.DateUtil;
import com.han.hotelplat.comm.utils.StrUtil;
import com.han.hotelplat.dao.employee.EmployeeDao;
import com.han.hotelplat.dao.emtask.EmtaskDao;
import com.han.hotelplat.dao.task.TaskDao;
import com.han.hotelplat.pojo.employee.Employee;
import com.han.hotelplat.pojo.emtask.Emtask;
import com.han.hotelplat.pojo.hhm.HotelHmanager;
import com.han.hotelplat.pojo.hotel.Hotel;
import com.han.hotelplat.pojo.hotelmanager.Hotelmanager;
import com.han.hotelplat.pojo.task.Task;
import com.han.hotelplat.service.emtask.EmTaskService;
import com.han.hotelplat.service.hhm.HotelHmanagerService;
import com.han.hotelplat.service.hotel.HotelService;
import com.han.hotelplat.service.hotelmanager.HotelmanagerService;

@Service
public class EmTaskServiceImpl implements EmTaskService{
	private Task task;
	
	@Autowired
	private EmtaskDao emtaskDao;
	@Autowired
	private TaskDao taskDao;
	@Autowired
	private EmployeeDao employeeDao;
	@Autowired
	private HotelService hotelService;
	@Autowired
	private EntityManage entityManage;
	@Autowired
	private HotelmanagerService hotelmanagerService;
	@Autowired
	private HotelHmanagerService hhmService;
	
	@Override
	public List<Emtask> getEmTaskByTakid(String taskid) {
		return emtaskDao.getEmTaskByTaskid(taskid);
	}

	@Override
	public Map<String, Object> acceptTask(String userid, String taskid, Integer optUserType,boolean force) {
		Map<String, Object> redata = new HashMap<String, Object>();
		List<Task> tli = taskDao.findByProperty("taskid", taskid);
		int count = emtaskDao.getEmTaskByTaskid(taskid).size();//已经接单的帮工人数
		
		Employee em = employeeDao.findEmployeeByUerid(userid);
		if(em.getState().intValue() != Constant.USER_STATE_PASS.intValue()){
			redata.put("code", -2);
			redata.put("message", "该状态不能接受任务");
			return redata;
		}
		
		Emtask emtold = emtaskDao.getEmTask(taskid,em.getUserid());//查询是否已经报名或者报名后已经取消了
		Emtask emt = null;
		if(tli.size() == 0){//任务不存在
			redata.put("code", -3);
			redata.put("message", "任务不存在");
			return redata;
		}
		Task t = tli.get(0);
		Hotel h = hotelService.getHotelById(t.getHotelid());
		if(optUserType.intValue() == Constant.USER_TYPE_EMPLOYEE.intValue()){
			if( t.getState().intValue() != Constant.TASK_STATE_CREAT.intValue()
					&& t.getState().intValue() != Constant.TASK_STATE_WAITSERVICE.intValue()){
				redata.put("code", -2);
				redata.put("message", "该任务已经停止报名了");
				return redata;
			}
		}else if(optUserType.intValue() == Constant.USER_TYPE_PLATFORM.intValue()){
			if( t.getState().intValue() != Constant.TASK_STATE_CREAT.intValue()
					&& t.getState().intValue() != Constant.TASK_STATE_WAITSERVICE.intValue()
					&& t.getState().intValue() != Constant.TASK_STATE_INSERVICE.intValue()){
				redata.put("code", -2);
				redata.put("message", "该任务已经停止报名了");
				return redata;
			}
		}
		
		//TODO判读酒店星级跟帮工星级
		if(optUserType.intValue() == Constant.USER_TYPE_EMPLOYEE.intValue() 
				&& h.getLevel().intValue()> em.getLevel().intValue()){
			redata.put("code", -2);
			redata.put("message", "您的清洁等级不匹配，请选择其他任务");
			return redata;
		}
		//人数已满
		if(optUserType.intValue() == Constant.USER_TYPE_EMPLOYEE.intValue() 
				&& count >= t.getUsercount().intValue()){
			redata.put("code", -2);
			redata.put("message", "该任务招收人数已满");
			return redata;
		}
		
		Date startTime = t.getStarttime();
		Date endTime = t.getEndtime();
		if(DateUtil.daysDistance(startTime, new Date())>0){
			redata.put("code", -2);
			redata.put("message", "该任务已经开始了");
			return redata;
		}
		//获取帮工非取消任务(按时间倒序)
		String hql = "select new Emtask(et.taskid, t.tasktype, et.creattime, et.starttime,"
				+ "et.endtime, et.reward, et.hotelid, et.canceltime,et.emid, "
				+ "et.cancercause)from Emtask as et, Task as t "
				+ "where t.taskid=et.taskid and t.state in(1,2,4)  and "
				+ "(et.canceltime is null or et.isstop is null) and et.emid ="+userid
				+" order by et.endtime ASC";
		List<Emtask> etli = emtaskDao.findByHQL(hql);
		boolean isAccept = false;//是否可以报名
		if(etli.size() == 0){
			isAccept = true;
		}else if(etli.size() == 1){
			Emtask emtask = etli.get(0);
			if(DateUtil.daysDistance(emtask.getEndtime(),startTime)>0
					|| DateUtil.daysDistance(emtask.getStarttime(),endTime)<0){
				isAccept = true;
			}
		}else{
			Emtask emtask = null;//上一个任务
			Emtask nextEt = null;//下一个任务
			Emtask firstEt = etli.get(0);
			Emtask lastEt= etli.get(etli.size()-1);
			if(DateUtil.daysDistance(lastEt.getEndtime(), startTime)>0
					|| DateUtil.daysDistance(firstEt.getStarttime(), endTime)<0){//
				isAccept = true;
			}else{
				for(int i =0 ; i<etli.size();i++){
					if(i == etli.size()-1){//最后一个
						emtask = etli.get(i-1);
						nextEt = etli.get(i);
					}else{
						emtask = etli.get(i);
						nextEt = etli.get(i+1);
					}
					System.out.println("endtime:"+DateUtil.formatYMD(emtask.getEndtime()));
					
					System.out.println("starttime:"+DateUtil.formatYMD(nextEt.getStarttime()));
					
					if(DateUtil.daysDistance(emtask.getEndtime(),startTime)>0
							&& DateUtil.daysDistance(nextEt.getStarttime(),endTime)<0){
						isAccept = true;
					}
				}
			}
		}
		
		//没报名过的
		if(emtold == null && !isAccept && !force){//时间冲突了并且没有强制报名
			redata.put("code", -1);
			redata.put("realname", em.getRealname());
			redata.put("message", "报名失败，该时段有未完成任务");
			return redata;
		}
		HotelHmanager hhm = null;
		Hotelmanager hm = null;
		String pushkey = "";
		if(t.getPublisher() != null){
			List<HotelHmanager> hmli= hhmService.getBindHotelManager(t.getHotelid(), t.getPublisher(), 1);
			if(hmli.size() == 1){
				hhm = hmli.get(0);
			}else{
				hmli= hhmService.getBindHotelManager(t.getHotelid(), null, 1);
				if(hmli.size() > 0){
					hhm = hmli.get(0);
				}
			}
			if(hhm != null){
				hm = hotelmanagerService.findByUserid(hhm.getHmuserid());
				pushkey = hm.getPushkey();
			}
			
		}

		//报名过
		if(emtold != null){
			emtold.setCanceltime(null);
			emtold.setCreattime(new Date());
			emtold.setCancercause(emtold.getCancercause()+"；帮工重新接单了");
			emtaskDao.update(emtold);
			
			//报名已满修改订单状态为待服务
			if(t.getUsercount().intValue() <= (count +1)){
				t.setState(Constant.TASK_STATE_WAITSERVICE);
				taskDao.update(t);
			}
			if(!StrUtil.isNullOrEmpty(pushkey)){
				JSONObject reqparam = new JSONObject();
				reqparam.put("taskId", taskid);
				AppHotelPushUtil.pushMessage(hm.getPushkey(), 
				"【有人有活】", hm.getRealname()+"您好，帮工"+em.getRealname()
				+ "报名了您的任务"+t.getTaskid()+"，请登录【有人有活App】查看详情。", "pageOrderDetail", reqparam);
		
			}
			redata.put("code", 0);
			redata.put("message", "任务接单成功");
			return redata;
		}
		
		//创建帮工任务
		emt = new Emtask();
		emt.setCreattime(new Date());
		emt.setEmid(userid);
		emt.setEndtime(t.getEndtime());
		emt.setHotelid(t.getHotelid());
		float reward = t.getUnitprice() * t.getLowestroom()
				*DateUtil.daysDistance(t.getStarttime(),t.getEndtime());
		emt.setReward(reward);
		emt.setStarttime(t.getStarttime());
		emt.setTaskid(t.getTaskid());
		emt.setUnitprice(h.getEmunitprice());//帮工单价
		emtaskDao.save(emt);
		if(!StrUtil.isNullOrEmpty(pushkey)){
			JSONObject reqparam = new JSONObject();
			reqparam.put("taskId", taskid);
			AppHotelPushUtil.pushMessage(hm.getPushkey(), 
			"【有人有活】", hm.getRealname()+"您好，帮工"+em.getRealname()
			+ "报名了您的任务"+t.getTaskid()+"，请登录【有人有活App】查看详情。", "pageOrderDetail", reqparam);
	
		}
		//报名已满修改订单状态为待服务
		if(t.getUsercount().intValue() <= (count +1)){
			t.setState(Constant.TASK_STATE_WAITSERVICE);
			taskDao.update(t);
			redata.put("code", 0);
			redata.put("message", "任务接单成功");
			return redata;
		}
		
		redata.put("code", 0);
		redata.put("message", "任务接单成功");
		return redata;
	}

	@Override
	public Emtask getEmTask(String taskid, String userid) {
		return emtaskDao.getEmTask(taskid, userid);
	}

	@Override
	public List<Emtask> getEmTaskByUserid(String userid) {
		return emtaskDao.getMyTaskByUserid(userid);
		
	}
	
	//判断帮工是否可以接单
	public int isAcceptTask(String userid, String taskid) {
		List<Task> tli = taskDao.findByProperty("taskid", taskid);

		Employee em = employeeDao.findEmployeeByUerid(userid);
		//待审核
		if(em.getState().intValue() == Constant.USER_STATE_CREAT.intValue()){
			return Constant.USER_STATE_CREAT.intValue();
		}
		//已冻结
		if(em.getState().intValue() == Constant.USER_STATE_FREEZE.intValue()){
			return Constant.USER_STATE_FREEZE.intValue();
		}
		//待审核
		if(em.getState().intValue() == Constant.USER_STATE_NO_PASS.intValue()){
			return Constant.USER_STATE_NO_PASS.intValue();
		}
		
		Emtask emtold = emtaskDao.getEmTask(taskid,em.getUserid());//查询是否已经报名或者报名后已经取消了
		if(emtold != null && (emtold.getCanceltime() == null 
				&& (emtold.getIsstop() == null || emtold.getIsstop().intValue() != 1))){
			return 5;//已报名
		}
		if(emtold != null && (emtold.getCanceltime() != null 
				|| (emtold.getIsstop() != null && emtold.getIsstop().intValue() == 1))){//报名后取消过
			return 7;//已取消
		}
		if(tli.size() == 0){//任务不存在
			return -2;//
		}
		
		Task t = tli.get(0);
		if(t.getState().intValue() != Constant.TASK_STATE_CREAT.intValue()
				&& t.getState().intValue() != Constant.TASK_STATE_WAITSERVICE.intValue()
				&& t.getState().intValue() != Constant.TASK_STATE_INSERVICE.intValue()){
			return -3;//可以分配帮工
		}
		
		/*//TODO判读酒店星级跟帮工星级
		if(h.getLevel().intValue()> em.getLevel().intValue()){
			redata.put("code", -2);
			redata.put("message", "您的清洁等级不匹配，请选择其他任务");
			return redata;
		}*/
		
		//人数已满
		/*if(count >= t.getUsercount().intValue()){
			return -4;
		}*/
		
		/*Date startTime = t.getStarttime();
		Date endTime = t.getEndtime();
		if(DateUtil.daysDistance(startTime, new Date())>0){
			redata.put("code", -2);
			redata.put("message", "报名失败，任务已经开始了");
			return redata;
		}*/
		
		//获取帮工非取消任务(按时间倒序)
		String hql = "select new Emtask(et.taskid, et.creattime, et.starttime,"
				+ "et.endtime, et.reward, et.hotelid, et.canceltime,et.emid, "
				+ "et.cancercause)from Emtask as et, Task as t "
				+ "where t.taskid=et.taskid and t.state in(1,2,4)  and "
				+ "(et.canceltime is null and et.isstop is null) and et.emid ="+userid
				+" order by et.endtime ASC";
		List<Emtask> etli = emtaskDao.findByHQL(hql);
		boolean isAccept = false;
		if(etli.size() == 0){
			isAccept = true;
		}else if(etli.size() == 1){
			Emtask emtask = etli.get(0);
			if(DateUtil.daysDistance(emtask.getEndtime(),t.getStarttime())>0
					|| DateUtil.daysDistance(emtask.getStarttime(),t.getEndtime())<0){
				isAccept = true;
			}
		}else{
			Emtask emtask = null;//上一个任务
			Emtask nextEt = null;//下一个任务
			Emtask firstEt = etli.get(0);
			Emtask lastEt= etli.get(etli.size()-1);
			if(DateUtil.daysDistance(lastEt.getEndtime(), t.getStarttime())>0
					|| DateUtil.daysDistance(firstEt.getStarttime(), t.getEndtime())<0){//
				isAccept = true;
			}else{
				for(int i =0 ; i<etli.size();i++){
					if(i == etli.size()-1){//最后一个
						emtask = etli.get(i-1);
						nextEt = etli.get(i);
					}else{
						emtask = etli.get(i);
						nextEt = etli.get(i+1);
					}
					System.out.println("endtime:"+DateUtil.formatYMD(emtask.getEndtime()));
					
					System.out.println("starttime:"+DateUtil.formatYMD(nextEt.getStarttime()));
					
					if(DateUtil.daysDistance(emtask.getEndtime(),t.getStarttime())>0
							&& DateUtil.daysDistance(nextEt.getStarttime(),t.getEndtime())<0){
						isAccept = true;
					}
				}
			}
		}
		
		if(!isAccept){
			//忙碌
			return 6;//忙碌状态
		}else{
			return 0;//空闲状态
		}
		
		
	}

	@Override
	public void save(Emtask emt) {
		emtaskDao.save(emt);
	}

	@Override
	public List<Emtask> getEmTaskByHotelid(String userid, Integer hotelid) {
		//获取帮工非取消任务(按时间倒序)
		String hql = "from Emtask where canceltime is null and emid ="+userid
				+" and hotelid="+hotelid+" order by endtime ASC";
		return emtaskDao.findByHQL(hql);
	}

	@Override
	public void update(Emtask emtold) {
		emtaskDao.update(emtold);
	}

	@Override
	public Emtask getEmFixedTask(String userid) {
		String hql = "from Emtask where emid='"+userid+"' and tasktype=1";
		List<Emtask> li = emtaskDao.findByHQL(hql);
		if(li != null && li.size() == 1){
			return li.get(0);
		}
		return null;
	}
	
	@Override
	public Map<String, Object> acceptTaskNew(String userid, String taskid, Integer optUserType) {
		Map<String, Object> redata = new HashMap<String, Object>();
		List<Task> tli = taskDao.findByProperty("taskid", taskid);
		Employee em = employeeDao.findEmployeeByUerid(userid);
		if(em.getState().intValue() != Constant.USER_STATE_PASS.intValue()){
			redata.put("code", -2);
			redata.put("message", "该状态不能接受任务");
			return redata;
		}
		
		Emtask emtold = emtaskDao.getEmTask(taskid,em.getUserid());//查询是否已经报名或者报名后已经取消了
		Emtask emt = null;
		if(tli.size() == 0){//任务不存在
			redata.put("code", -3);
			redata.put("message", "任务不存在");
			return redata;
		}
		Task t = tli.get(0);
		Hotel h = hotelService.getHotelById(t.getHotelid());
		if(optUserType.intValue() == Constant.USER_TYPE_PLATFORM.intValue()){
			if( t.getState().intValue() != Constant.TASK_STATE_CREAT.intValue()
					&& t.getState().intValue() != Constant.TASK_STATE_WAITSERVICE.intValue()
					&& t.getState().intValue() != Constant.TASK_STATE_INSERVICE.intValue()){
				redata.put("code", -2);
				redata.put("message", "该任务已经停止报名了");
				return redata;
			}
		}
		
		//TODO判读酒店星级跟帮工星级
		if(optUserType.intValue() == Constant.USER_TYPE_EMPLOYEE.intValue() 
				&& h.getLevel().intValue()> em.getLevel().intValue()){
			redata.put("code", -2);
			redata.put("message", "您的清洁等级不匹配，请选择其他任务");
			return redata;
		}
		HotelHmanager hhm = null;
		Hotelmanager hm = null;
		String pushkey = "";
		if(t.getPublisher() != null){
			List<HotelHmanager> hmli= hhmService.getBindHotelManager(t.getHotelid(), t.getPublisher(), 1);
			if(hmli.size() == 1){
				hhm = hmli.get(0);
			}else{
				hmli= hhmService.getBindHotelManager(t.getHotelid(), null, 1);
				if(hmli.size() > 0){
					hhm = hmli.get(0);
				}
			}
			if(hhm != null){
				hm = hotelmanagerService.findByUserid(hhm.getHmuserid());
				pushkey = hm.getPushkey();
			}
			
		}

		//报名过
		if(emtold != null){
			emtold.setCanceltime(null);
			emtold.setCreattime(new Date());
			emtold.setCancercause(emtold.getCancercause()+"；帮工重新接单了");
			emtaskDao.update(emtold);
			if(!StrUtil.isNullOrEmpty(pushkey)){
				JSONObject reqparam = new JSONObject();
				reqparam.put("taskId", taskid);
				AppHotelPushUtil.pushMessage(hm.getPushkey(), 
				"【有人有活】", hm.getRealname()+"您好，帮工"+em.getRealname()
				+ "报名了您的任务"+t.getTaskid()+"，请登录【有人有活App】查看详情。", "pageOrderDetail", reqparam);
		
			}
			redata.put("code", 0);
			redata.put("message", "任务接单成功");
			return redata;
		}
		
		//创建帮工任务
		emt = new Emtask();
		emt.setCreattime(new Date());
		emt.setEmid(userid);
		emt.setEndtime(t.getEndtime());
		emt.setHotelid(t.getHotelid());
		float reward = t.getUnitprice() * t.getLowestroom()
				*DateUtil.daysDistance(t.getStarttime(),t.getEndtime());
		emt.setReward(reward);
		emt.setStarttime(t.getStarttime());
		emt.setTaskid(t.getTaskid());
		emt.setUnitprice(h.getEmunitprice());//帮工单价
		emtaskDao.save(emt);
		if(!StrUtil.isNullOrEmpty(pushkey)){
			JSONObject reqparam = new JSONObject();
			reqparam.put("taskId", taskid);
			AppHotelPushUtil.pushMessage(hm.getPushkey(), 
			"【有人有活】", hm.getRealname()+"您好，帮工"+em.getRealname()
			+ "报名了您的任务"+t.getTaskid()+"，请登录【有人有活App】查看详情。", "pageOrderDetail", reqparam);
	
		}
		redata.put("code", 0);
		redata.put("message", "任务接单成功");
		return redata;
	}
}
